//
//  RickyRefreshNormal.m
//  Ricky_RefreshControl
//
//  Created by MR-zhang on 15/7/2.
//  Copyright (c) 2015年 Ricky. All rights reserved.
//

#import "RickyRefreshNormal.h"

/**
 * 关于画对勾和叉的方法：
 叉号：把一个圆形高度四等分，叉号两条线的四个点坐标位于，等分线的边际第一个交叉点。
 对勾：实际根据等分调整。
 */
//=====================================

NSString *const RickyAnimationKey = @"com.Refresh.rotation";

static CGFloat const RikcyLayerRadius = 12.0f;

// 文字和图片之间的间距
static CGFloat const RickyTextImageMargin = 20.0f;

// CAShapeLayer 的结束点。
static CGFloat const RickyStrokeEnd = 0.95;

@interface RickyRefreshNormal ()

/** 指示标题 */
@property (nonatomic, strong) UILabel *titleLabel;

/** 动画指针 */
@property (nonatomic, strong) CAShapeLayer *imageLayer;

/** 动画圆形轨迹 */
@property (nonatomic, strong) CAShapeLayer *arcLayer;

/** 结束刷新时，正确指示图层 */
@property (nonatomic, strong) CAShapeLayer *checkMarkLayer;

/** 结束刷新时，错误指示图层 */
@property (nonatomic, strong) CAShapeLayer *unCheckMarkLayer;

/** 刷新视图类型. */
@property (nonatomic, assign) RickyRefreshViewType viewType;

/**
 开始动画.
 在（setRefreshState）中调用，如果state=RickyRefreshStateRefreshing,开始动画。
 */
- (void)startAnimations;

/** 结束动画. */
- (void)removeAnimations;

/** 调整控件大小. */
- (void)adjustShapeLayerPath;

@end

@implementation RickyRefreshNormal

#pragma mark -- 加载控件
- (UILabel *)titleLabel
{
    if (!_titleLabel) {
        _titleLabel = ({
            UILabel *label = [[UILabel alloc] init];
            label.backgroundColor = [UIColor clearColor];
            label.font = [UIFont systemFontOfSize:RickyHeaderTitleFontSize];
            label.textColor = [UIColor blackColor];
            label.textAlignment = 1;
            label;
        });
        [self insertSubview:_titleLabel atIndex:0];
    }
    return _titleLabel;
}

- (void)addImageLayer
{
    _imageLayer = [CAShapeLayer layer];
    _imageLayer.lineCap = kCALineCapRound;
    _imageLayer.lineJoin = kCALineJoinRound;
    _imageLayer.strokeColor = RickyStrokeColor.CGColor;
    _imageLayer.lineWidth = 4;
    [self.layer addSublayer:_imageLayer];
}

- (void)addShapeLayer
{
    _arcLayer = [CAShapeLayer layer];
    _arcLayer.lineCap = kCALineCapRound;
    _arcLayer.lineJoin = kCALineJoinRound;
    _arcLayer.fillColor = [UIColor clearColor].CGColor;
    _arcLayer.strokeColor = RickyStrokeColor.CGColor;
    _arcLayer.lineWidth = 2;
    _arcLayer.strokeStart = 0;
    [self.layer addSublayer:_arcLayer];
}

- (void)addCheckMarkLayer
{
    _checkMarkLayer = [CAShapeLayer layer];
    _checkMarkLayer.lineCap = kCALineCapButt;
    _checkMarkLayer.lineJoin = kCALineJoinRound;
    _checkMarkLayer.fillColor = [UIColor clearColor].CGColor;
    _checkMarkLayer.strokeColor = RickyMarkColor.CGColor;
    _checkMarkLayer.lineWidth = 1;
    _checkMarkLayer.strokeStart = 0;
    _checkMarkLayer.strokeEnd = 1;
    _checkMarkLayer.hidden = YES;
    [self.layer addSublayer:_checkMarkLayer];
}

- (void)addUnCheckMarkLayer
{
    _unCheckMarkLayer = [CAShapeLayer layer];
    _unCheckMarkLayer.lineCap = kCALineCapButt;
    _unCheckMarkLayer.lineJoin = kCALineJoinRound;
    _unCheckMarkLayer.fillColor = [UIColor clearColor].CGColor;
    _unCheckMarkLayer.strokeColor = RickyMarkColor.CGColor;
    _unCheckMarkLayer.lineWidth = 1;
    _unCheckMarkLayer.strokeStart = 0;
    _unCheckMarkLayer.strokeEnd = 1;
    _unCheckMarkLayer.hidden = YES;
    [self.layer addSublayer:_unCheckMarkLayer];
}

#pragma mark -- init
- (id)initWithRefreshViewType:(RickyRefreshViewType)viewType
{
    self = [super initWithRefreshViewType:viewType];
    if (self) {
        self.observersEnabled = YES;
        [self addImageLayer];
        [self addShapeLayer];
        [self addCheckMarkLayer];
        [self addUnCheckMarkLayer];
        _viewType = viewType;
        [self setRefreshViewTitleWithType:viewType];

    }
    return self;
}

#pragma mark -- 渲染页面调整各部分控件
- (void)layoutSubviews
{
    [super layoutSubviews];
    
    [self adjustShapeLayerPath];
}

- (void)adjustShapeLayerPath
{
    if (_titleLabel) {
        CGSize titleSize = MB_TEXTSIZE(_titleLabel.text, [UIFont systemFontOfSize:RickyHeaderTitleFontSize]);
        _titleLabel.frame = CGRectMake(0, (self.bounds.size.height-titleSize.height)/2, self.bounds.size.width, titleSize.height);
    }
    
    if (_imageLayer) {
        /*
         _titleLabel在最下面，它位于整个视图的中间位置
         得到_titleLabel文字的size,然后计算_imageView的x,y
         */
        CGSize titleSize = MB_TEXTSIZE(_titleLabel.text, [UIFont systemFontOfSize:RickyHeaderTitleFontSize]);
        CGFloat originalX = self.bounds.size.width*0.5 - titleSize.width - RickyTextImageMargin;
        _imageLayer.frame = CGRectMake(originalX, (self.bounds.size.height-RikcyLayerRadius*2)/2, RikcyLayerRadius*2, RikcyLayerRadius*2);
        
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(RikcyLayerRadius, 0)];
        [path addLineToPoint:CGPointMake(RikcyLayerRadius, RikcyLayerRadius)];
        _imageLayer.path = path.CGPath;
    }
    
    if (_arcLayer) {
        _arcLayer.frame = _imageLayer.frame;
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path addArcWithCenter:CGPointMake(_arcLayer.frame.size.width/2, _arcLayer.frame.size.height/2) radius:RikcyLayerRadius startAngle:-M_PI_2 endAngle:2*M_PI-M_PI_2 clockwise:YES];
        _arcLayer.path = path.CGPath;
    }
    
    if (_checkMarkLayer) {
        CGFloat marginLen = 2;
        _checkMarkLayer.frame = CGRectMake(_imageLayer.frame.origin.x+4*marginLen, _imageLayer.frame.origin.y+marginLen, _imageLayer.frame.size.width-2*marginLen, _imageLayer.frame.size.height-2*marginLen);
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path addArcWithCenter:CGPointMake(_checkMarkLayer.frame.size.width/2, _checkMarkLayer.frame.size.height/2) radius:(RikcyLayerRadius-marginLen) startAngle:-M_PI_2 endAngle:2*M_PI-M_PI_2 clockwise:YES];
        _checkMarkLayer.path = path.CGPath;
        CGFloat partLen = _checkMarkLayer.frame.size.height/4;
        [path moveToPoint:CGPointMake(partLen*0.75, partLen*1.5)];
        [path addLineToPoint:CGPointMake(partLen*1.5, partLen*3)];
        [path addLineToPoint:CGPointMake(partLen*3.3, partLen*1.2)];
        [path moveToPoint:CGPointMake(partLen*0.75, partLen*1.5)];
        [path closePath];
        _checkMarkLayer.path = path.CGPath;
    }
    
    if (_unCheckMarkLayer) {
        CGFloat marginLen = 2;
        _unCheckMarkLayer.frame = CGRectMake(_imageLayer.frame.origin.x+4*marginLen, _imageLayer.frame.origin.y+marginLen, _imageLayer.frame.size.width-2*marginLen, _imageLayer.frame.size.height-2*marginLen);
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path addArcWithCenter:CGPointMake(_unCheckMarkLayer.frame.size.width/2, _unCheckMarkLayer.frame.size.height/2) radius:(RikcyLayerRadius-marginLen) startAngle:-M_PI_2 endAngle:2*M_PI-M_PI_2 clockwise:YES];
        _unCheckMarkLayer.path = path.CGPath;
        CGFloat partLen = _unCheckMarkLayer.frame.size.height/4;
        [path moveToPoint:CGPointMake(partLen, partLen)];
        [path addLineToPoint:CGPointMake(3*partLen, 3*partLen)];
        [path moveToPoint:CGPointMake(partLen, 3*partLen)];
        [path addLineToPoint:CGPointMake(3*partLen, partLen)];
        [path closePath];
        _unCheckMarkLayer.path = path.CGPath;
    }
}

#pragma mark -- 重写父类某些属性
- (void)setRefreshViewTitleWithType:(RickyRefreshViewType)viewType
{
    if (viewType == RickyRefreshViewTypeHeader) {
        [self.titleLabel setText:RickyHeaderNormalTitle];
    } else {
        [self.titleLabel setText:RickyFooterNormalTitle];
    }
}

- (void)setRefreshState:(RickyRefreshState)refreshState
{
    [super setRefreshState:refreshState];
    if (refreshState == RickyRefreshStateRefreshing) {
        
        __weak __typeof(self)weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong __typeof(weakSelf)strongSelf = weakSelf;
            [strongSelf.titleLabel setText:_viewType==RickyRefreshViewTypeHeader?RickyHeaderRefreshingTitle:RickyFooterRefreshingTitle];
            [strongSelf startAnimations];
        });
    }
}

- (void)setCompleteType:(RickyRefreshCompleteType)completeType
{
    [super setCompleteType:completeType];
    /*
     1.停止动画
     2.设置各图层的hidden属性
     3.设置complete文本
     4.在callBack回调中把文本复原（不能在setRefreshState里复原文本，会出现，文本先变成下拉刷新，然后再回弹的情况）
     */
    [self removeAnimations];
    
    void(^hiddenBlock)(BOOL hidden) = ^(BOOL hidden){
        _imageLayer.hidden = hidden;
        _arcLayer.hidden = hidden;
        _checkMarkLayer.hidden = !hidden;
        _unCheckMarkLayer.hidden = !hidden;
    };
    
    // 设置标题的title
    NSString *contentString = nil;
    switch (completeType) {
        case RickyRefreshCompleteTypeSuccess:
        {
            contentString = _viewType==RickyRefreshViewTypeHeader ? RickyHeaderSuccessCompleteTitle : RickyFooterSuccessCompleteTitle;
        } break;
            
        case RickyRefreshCompleteTypeNoData:
        {
            contentString = _viewType==RickyRefreshViewTypeHeader ? RickyHeaderNoDataCompleteTitle : RickyFooterNoDataCompleteTitle;
        } break;
            
        case RickyRefreshCompleteTypeError:
        {
            contentString = _viewType==RickyRefreshViewTypeHeader ? RickyHeaderErrorCompleteTitle : RickyFooterNoDataCompleteTitle;
        } break;
    }
    
    [self.titleLabel setText:contentString];
    
    // 设置layer的hidden属性
    hiddenBlock(YES);
    
    // 根据类型设置符号
    [self drawMarkWithCompleteType:completeType];
    
    // 设置完成回调
    __weak __typeof(self)weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(RickyCompleteDuration*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        __weak __typeof(strongSelf)weakSelf = strongSelf;
        [strongSelf setRefreshState:RickyRefreshStateNormal withCallBack:^{
            __strong __typeof(weakSelf)strongSelf = weakSelf;
            NSString *noteString = _viewType == RickyRefreshViewTypeHeader ? RickyHeaderNormalTitle:RickyFooterNormalTitle;
            [strongSelf.titleLabel setText:noteString];
            hiddenBlock(NO);
        }];
    });
}

- (void)setRefreshRatio:(CGFloat)refreshRatio
{
    if (refreshRatio == 1.0) {
        refreshRatio = RickyStrokeEnd;
    }
    _arcLayer.strokeEnd = refreshRatio + 0.8*refreshRatio;
}

#pragma mark -- 动画
- (void)startAnimations
{
    // Remove animation first.
    [self removeAnimations];
    
    // Add animatioin.
    _arcLayer.strokeEnd = RickyStrokeEnd + 0.01;// 为了让动画连贯起来。
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.fromValue = @(0.0);
    animation.toValue = @(2 * M_PI);
    animation.duration = 1.0;
    animation.repeatCount = INT_MAX;
    [_arcLayer addAnimation:animation forKey:RickyAnimationKey];
    
    animation.toValue = @(-2 * M_PI);
    [_imageLayer addAnimation:animation forKey:RickyAnimationKey];

}

- (void)removeAnimations{
    [_arcLayer removeAnimationForKey:RickyAnimationKey];
    [_imageLayer removeAnimationForKey:RickyAnimationKey];
}

#pragma mark -- 绘制结束标题提示图层
- (void)drawMarkWithCompleteType:(RickyRefreshCompleteType)type
{
    if (type==RickyRefreshCompleteTypeSuccess || type==RickyRefreshCompleteTypeNoData) {
        _checkMarkLayer.hidden = NO;
        _unCheckMarkLayer.hidden = YES;
    } else {
        _checkMarkLayer.hidden = YES;
        _unCheckMarkLayer.hidden = NO;
    }
}

#pragma mark -- 添加从后台返回通知，保证动画正常进行不会停止
- (void)reloadNotification:(NSNotification *)notification
{
    if (self.refreshState == RickyRefreshStateRefreshing) {
        [self startAnimations];
    }
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
